//
//  YuanXinCookieManager.m
//  yuanxinwebview
//
//  Created by 晏德智 on 2016/12/26.
//  Copyright © 2016年 晏德智. All rights reserved.
//

#import "YuanXinCookieManager.h"
#import <WebKit/WebKit.h>
#import "YuanXinWebView.h"

@implementation YuanXinCookieManager

RCT_EXPORT_MODULE()

- (dispatch_queue_t)methodQueue
{
    return dispatch_get_main_queue();
}

RCT_EXPORT_METHOD(set:(NSDictionary *)props callback:(RCTResponseSenderBlock)callback) {
    NSString *name = [RCTConvert NSString:props[@"name"]];
    NSString *value = [RCTConvert NSString:props[@"value"]];
    NSString *domain = [RCTConvert NSString:props[@"domain"]];
    NSString *origin = [RCTConvert NSString:props[@"origin"]];
    NSString *path = [RCTConvert NSString:props[@"path"]];
    NSString *version = [RCTConvert NSString:props[@"version"]];
    NSDate *expiration = [RCTConvert NSDate:props[@"expiration"]];

    NSMutableDictionary *cookieProperties = [NSMutableDictionary dictionary];
    [cookieProperties setObject:name ?: @"" forKey:NSHTTPCookieName];
    [cookieProperties setObject:value ?: @"" forKey:NSHTTPCookieValue];
    [cookieProperties setObject:domain ?: @"" forKey:NSHTTPCookieDomain];
    [cookieProperties setObject:origin ?: @"" forKey:NSHTTPCookieOriginURL];
    [cookieProperties setObject:path ?: @"" forKey:NSHTTPCookiePath];
    [cookieProperties setObject:version ?: @"" forKey:NSHTTPCookieVersion];
    [cookieProperties setObject:expiration ?: @"" forKey:NSHTTPCookieExpires];

    NSLog(@"SETTING COOKIE");
    NSLog(@"%@", cookieProperties);

    NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:cookieProperties];
    [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];

    // iOS 11.0 WKHttpCookieStore
    if (NSClassFromString(@"WKHTTPCookieStore")) {
        if (@available(iOS 11.0, *)) {
            WKHTTPCookieStore *cookieStore = [WKWebsiteDataStore defaultDataStore].httpCookieStore;
            [cookieStore setCookie:cookie completionHandler:^{
                if (callback) {
                    callback(@[[NSNull null]]);
                }
            }];
        } else {
            // Fallback on earlier versions
            if (callback) {
                callback(@[[NSNull null]]);
            }
        };
    } else {
        if (callback) {
            callback(@[[NSNull null]]);
        }
    }
}

RCT_EXPORT_METHOD(setFromResponse:(NSURL *)url value:(NSDictionary *)value callback:(RCTResponseSenderBlock)callback) {
    NSArray *cookies = [NSHTTPCookie cookiesWithResponseHeaderFields:value forURL:url];
    [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookies:cookies forURL:url mainDocumentURL:NULL];

    // iOS 11.0 WKHttpCookieStore
    if (@available(iOS 11.0, *)) {
        WKHTTPCookieStore *cookieStore = [WKWebsiteDataStore defaultDataStore].httpCookieStore;
        for (NSHTTPCookie *cookie in cookies) {
            [cookieStore setCookie:cookie completionHandler:^{
                if (callback) {
                    callback(@[[NSNull null]]);
                }
            }];
        }
    } else {
        // Fallback on earlier versions
        if (callback) {
            callback(@[[NSNull null]]);
        }
    }
}


RCT_EXPORT_METHOD(get:(NSURL *)url callback:(RCTResponseSenderBlock)callback) {
    NSMutableDictionary *cookies = [NSMutableDictionary dictionary];
    NSArray *arrCookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:url];
    for (NSHTTPCookie *c in arrCookies) {
        if (c.name && c.value) {
            [cookies setObject:c.value forKey:c.name];
        }
    }
    if (cookies.count == 0) {
        // iOS 11.0 WKHttpCookieStore
        if (@available(iOS 11.0, *)) {
            WKHTTPCookieStore *cookieStore = [WKWebsiteDataStore defaultDataStore].httpCookieStore;
            [cookieStore getAllCookies:^(NSArray<NSHTTPCookie *> * arrayCookies) {
                for (NSHTTPCookie *c in arrayCookies) {
                    if (c.name && c.value) {
                        [cookies setObject:c.value forKey:c.name];
                    }
                }
                if (callback) {
                    callback(@[[NSNull null], cookies]);
                }
            }];
        } else {
            // Fallback on earlier versions
            if (callback) {
                callback(@[[NSNull null], cookies]);
            }
        };
    } else {
        if (callback) {
            callback(@[[NSNull null], cookies]);
        }
    }
}

RCT_EXPORT_METHOD(clearAll:(RCTResponseSenderBlock)callback) {
    NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
    for (NSHTTPCookie *c in cookieStorage.cookies) {
        [cookieStorage deleteCookie:c];
    }
    // iOS 11.0 WKHttpCookieStore
    if (@available(iOS 11.0, *)) {
        // 方法一
        WKHTTPCookieStore *cookieStore = [WKWebsiteDataStore defaultDataStore].httpCookieStore;
        [cookieStore getAllCookies:^(NSArray<NSHTTPCookie *> * arrayCookies) {
            __block NSInteger finishedCount = 0;
            NSInteger total = arrayCookies.count;
            if (total == 0) {
                if (callback) {
                    callback(@[[NSNull null]]);
                }
            } else {
                for (NSHTTPCookie *c in arrayCookies) {
                    [cookieStore deleteCookie:c completionHandler:^{
                        finishedCount++;
                        if (finishedCount >= total) {
                            if (callback) {
                                callback(@[[NSNull null]]);
                            }
                        }
                    }];
                }
            }
        }];

        /*
        // 方法二
        WKWebsiteDataStore *dateStore = [WKWebsiteDataStore defaultDataStore];
        [dateStore fetchDataRecordsOfTypes:[WKWebsiteDataStore allWebsiteDataTypes]
                         completionHandler:^(NSArray<WKWebsiteDataRecord *> * __nonnull records) {
                             __block NSInteger finishedCount = 0;
                             NSInteger total = records.count;
                             if (total == 0) {
                                 if (callback) {
                                     callback(@[[NSNull null]]);
                                 }
                             } else {
                                 for (WKWebsiteDataRecord *record in records){
                                     //if ([record.displayName isEqualToString:baseDomain]){
                                     if ([record.displayName containsString:@"sinooceangroup"]){
                                         //判断如果是我们自己的域名那么删除该域名下的Cookies
                                         [[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:record.dataTypes forDataRecords:@[record] completionHandler:^{
                                             finishedCount++;
                                             if (finishedCount >= total) {
                                                 if (callback) {
                                                     callback(@[[NSNull null]]);
                                                 }
                                             }
                                         }];
                                     } else {
                                         finishedCount++;
                                         if (finishedCount >= total) {
                                             if (callback) {
                                                 callback(@[[NSNull null]]);
                                             }
                                         }
                                     }
                                 }
                             }
                         }];
        */
    } else {
        // Fallback on earlier versions
        if (callback) {
            callback(@[[NSNull null]]);
        }
    };
}

RCT_EXPORT_METHOD(clearByName:(NSString *)name callback:(RCTResponseSenderBlock)callback) {
    NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
    for (NSHTTPCookie *c in cookieStorage.cookies) {
        if ([[c name] isEqualToString:name]) {
            [cookieStorage deleteCookie:c];
        }
    }
    // iOS 11.0 WKHttpCookieStore
    if (@available(iOS 11.0, *)) {
        WKHTTPCookieStore *cookieStore = [WKWebsiteDataStore defaultDataStore].httpCookieStore;
        [cookieStore getAllCookies:^(NSArray<NSHTTPCookie *> * arrayCookies) {
            __block NSInteger loopCount = 0;
            if (arrayCookies.count == 0) {
                if (callback) {
                    callback(@[[NSNull null]]);
                }
            } else {
                for (NSHTTPCookie *c in arrayCookies) {
                    if ([[c name] isEqualToString:name]) {
                        [cookieStore deleteCookie:c completionHandler:^{
                            loopCount++;
                            if (loopCount == arrayCookies.count && callback) {
                                callback(@[[NSNull null]]);
                            }
                        }];
                    } else {
                        loopCount++;
                        if (loopCount == arrayCookies.count && callback) {
                            callback(@[[NSNull null]]);
                        }
                    }
                }
            }
        }];
    } else {
        // Fallback on earlier versions
        if (callback) {
            callback(@[[NSNull null]]);
        }
    };
}

// TODO: return a better formatted list of cookies per domain
RCT_EXPORT_METHOD(getAll:(RCTResponseSenderBlock)callback) {
    NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
    NSMutableDictionary *cookies = [NSMutableDictionary dictionary];
    for (NSHTTPCookie *c in cookieStorage.cookies) {
        NSMutableDictionary *d = [NSMutableDictionary dictionary];
        [d setObject:c.value ?: @"" forKey:@"value"];
        [d setObject:c.name ?: @"" forKey:@"name"];
        [d setObject:c.domain ?: @"" forKey:@"domain"];
        [d setObject:c.path ?: @"" forKey:@"path"];
        [cookies setObject:d forKey:c.name];
    }
    if (callback) {
        callback(@[[NSNull null], cookies]);
    }
}

#pragma mark - 清除 webview 缓存

RCT_EXPORT_METHOD(clearWebviewCache:(RCTResponseSenderBlock)callback) {
    [YuanXinWebView clearWbCache];
    if (callback) {
        callback(@[[NSNull null]]);
    }
}

@end
